package logic

import (
	sdk "chainmaker.org/chainmaker/sdk-go/v2"
	"context"
	"database/sql"
	"errors"
	"fmt"
	"github.com/ethereum/go-ethereum/accounts/abi"
	"github.com/zeromicro/go-zero/core/logx"
	"zero-demo-rpc/chainmaker"
	"zero-demo-rpc/chainmaker/cryptogen/config"
	"zero-demo-rpc/mall/Register/api/internal/svc"
	"zero-demo-rpc/mall/Register/api/internal/types"
)

const env = "mylocal"

// 长安链
type ChainMaker struct {
	cc              *sdk.ChainClient
	myAbi           *abi.ABI
	cryptoGenConfig *config.CryptoGenConfig
	sdkConfPath     string
}

type UserRegisterLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

type info struct {
	name       string `db:"name"`
	address    string `db:"address"`
	signcrt    string `db:"sign_crt"`
	signkey    string `db:"sign_key"`
	tlscrt     string `db:"tls_crt"`
	tlskey     string `db:"tls_key"`
	productsum int    `db:"product_sum"`
}

var chainMaker *ChainMaker
var basePath string
var contractName string
var admin1addr string
var clientaddr string

var sdkConfPath, nftABIPath, cryptoGenConfPath string

func init() {
	//var sdkConfPath, nftABIPath, cryptoGenConfPath string
	switch env {

	case "mylocal":
		//   /home/
		sdkConfPath = "/home/zero-demo-rpc/chainmaker/example/config_mylocal/sdk_config_org1_admin1.yml"
		nftABIPath = "/home/zero-demo-rpc/chainmaker/example/config_mylocal/nft_normal.abi"
		cryptoGenConfPath = "/home/zero-demo-rpc/chainmaker/example/config_mylocal/crypto_config.yml"
		basePath = "/home/zero-demo-rpc/chainmaker/example/config_mylocal/wx-org1.chainmaker.org"
		contractName = "nft_normal"
		//admin1addr = "0x435efa08c7d7cfb9cc06ba572f2cad9e53060fb6"
		admin1addr = "0x55f00c94f8579a75be0fc896c87b79cca963f2ab"
		//admin1addr = "0x435EFa08c7D7cfb9CC06Ba572F2Cad9e53060FB6"
		clientaddr = "0x7201baffd306fc10ef82b38d9a761ca0e2c6d6c3"
	}

	print(sdkConfPath, "\n", nftABIPath, "\n", cryptoGenConfPath, "\n")

	_, err := chainmaker.NewChainMaker(sdkConfPath, nftABIPath, cryptoGenConfPath)
	if err != nil {
		fmt.Println(err)
		return
	}
}

func NewUserRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserRegisterLogic {
	return &UserRegisterLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UserRegisterLogic) UserRegister(req *types.RegisterReq) (resp *types.RegisterReply, err error) {
	// todo: add your logic here and delete this line

	db, err := sql.Open("mysql", "root:huohuo@tcp(127.0.0.1:3306)/test_2?charset=utf8")
	//root为数据库用户名，后面为密码，tcp代表tcp协议，test处填写自己的数据库名称
	if err != nil {
		fmt.Println("数据库链接失败")
		return nil, errors.New("")
	}

	result, err := db.Exec("INSERT INTO user(user_name,user_address,sign_crt,sign_key,tls_crt,tls_key,product_sum) VALUES (?,?,?,?,?,?,?)", req.UserName, "", "", "", "", "", 0)

	fmt.Println(result)

	if err != nil {
		fmt.Println("创建用户失败:", err)
		return nil, errors.New("")
	} else {
		fmt.Println("正在尝试创建用户")

		//var sdkConfPath, nftABIPath, cryptoGenConfPath string
		//print(sdkConfPath, "\n", nftABIPath, "\n", cryptoGenConfPath, "\n")

		//建立上传用户连接
		cm, err := chainmaker.NewChainMaker(sdkConfPath, nftABIPath, cryptoGenConfPath)

		if err != nil {
			fmt.Println(err)
			return nil, errors.New("")
		}

		fmt.Println("用户数据库创建成功")

		//生成用户证书,name只能为小写字符+数字
		signCrt, signKey, tlsCrt, tlsKey, err := cm.GenerateUserCrt(req.UserName) //返回四个证书字符串
		//其实api帮我们把用户证书保存到本地了，这里重定向为UserCerts下面

		if err != nil {
			fmt.Println("生成证书失败：", err)
		} else {
			//fmt.Println(signCrt, signKey, tlsCrt, tlsKey)
			//将四个字段添加到数据库中

			_, err = db.Exec("UPDATE user SET sign_crt=?,sign_key=?,tls_crt=?,tls_key=? where user_name=?", signCrt, signKey, tlsCrt, tlsKey, req.UserName)

			//不需要额外的转换了
			//chainmaker.BuildUserCrt()

			//tmp := "C://sers/DELL/Desktop/golang/nft_xmu_backend/zero-demo-rpc/mall/Register/api/wx-org1.chainmaker.org/user/" + req.UserName
			//为用户添加证书，从而获得唯一的哈希地址

			//certHash, err := cm.AddCertByPath(tmp+".tls.key", tmp+".tls.crt", tmp+".sign.key", tmp+".sign.crt")
			certHash, err := cm.AddCert(signCrt, signKey, tlsCrt, tlsKey)
			//fmt.Println("证书地址：", tmp+".tls.key")

			if err != nil {
				fmt.Println("添加证书失败", err)
			} else {
				fmt.Println("添加证书成功，CertHash:", certHash)

				_, err = db.Exec("UPDATE user SET user_address=? where user_name=?", certHash, req.UserName)

				if err != nil {
					fmt.Println("添加至数据库失败")
					return nil, err
				} else {
					fmt.Println("创建用户成功")
					return &types.RegisterReply{
						UserAddress: certHash,
					}, nil
				}

			}
		}
	}
	return nil, nil
}

func check(err error) { //因为要多次检查错误，所以干脆自己建立一个函数。
	if err != nil {
		fmt.Println(err)
	}
}
